package com.fashion.web.actions.management;

import com.fashion.exceptions.AdminException;
import com.fashion.model.Administrator;
import com.fashion.service.UserService;
import com.fashion.utils.AdministratorResult;
import com.fashion.utils.ConstItem;
import com.fashion.utils.ManagementUtils;
import com.fashion.utils.StringUtils;
import com.fashion.utils.security.SecurityCode;
import com.fashion.utils.security.SecurityImage;
import com.opensymphony.xwork2.ActionSupport;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by
 * User: keviyang
 * Date: 11-4-26
 */
@Scope("prototype")
@Controller
@Namespace("/management")
@ParentPackage("json-default")
public class ManagementAction extends ActionSupport implements SessionAware, ServletRequestAware, ServletResponseAware {
    private static final Logger logger = Logger.getLogger(ManagementAction.class);
    private int page;
    private int rows;
    private String userId;

    private String userName;
    private String password;
    private boolean errorLogin = false;

    private UserService userService;
    private Map<String, Object> session;
    private Map<String, Object> dataGridView;
    private AdministratorResult administratorResult;
    private Administrator userForm;
    private String jsonResult;
    private HttpServletRequest request;
    private HttpServletResponse response;
    private ByteArrayInputStream imageStream;
    private String securityCode;

    @Action(value = "preLogin", results = {@Result(name = SUCCESS, location = "management_login.jsp")})
    public String preLogin() throws Exception {
        return SUCCESS;
    }

    @Action(value = "generateSecurityImage", results = {@Result(name = SUCCESS, type = "stream", params = {
            "contentType", "image/jpeg",
            "inputName", "imageStream",
            "bufferSize", "4096"})})
    public String generateSecurityImage() throws Exception {
        String securityCode = SecurityCode.getSecurityCode();
        imageStream = SecurityImage.getImageAsInputStream(securityCode);
        session.put("SESSION_SECURITY_CODE", securityCode);
        return SUCCESS;
    }

    //  @Action(value = "login", results = {@Result(name = SUCCESS, location = "index.action", type = "redirectAction"),@Result(name = INPUT, location = "management_login.jsp")})
    //  @Action(value = "createaboutnews",results = {@Result(name=SUCCESS,params = {"activityId", "${activityId}"},location = "addaboutnews",type = "chain")})
    @Action(value = "login", results = {@Result(name = SUCCESS, location = "management_index.jsp"), @Result(name = INPUT, location = "management_login.jsp")})
    public String login() throws Exception {
        //清除登陆页面缓存
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Cache-Control", "no-store");
        response.setDateHeader("Expires", 0);

        String serverCode = (String) session.get("SESSION_SECURITY_CODE");
        if (null == serverCode || !serverCode.equals(securityCode)) {
            logger.info("gnyk: securityCode error, input securityCode is: " + serverCode + " while serverCode is: " + serverCode);
            return INPUT;
        }

        if (null != session.get(ConstItem.USER_NAME_IN_SESSION)) {
            logger.info("gnyk: securityCode error, input securityCode is: " + serverCode + " while serverCode is: " + serverCode);
            return SUCCESS;
        }

        Administrator user = userService.validateLogin(userName, password);

        if (null != user) {
            session.put(ConstItem.USER_NAME_IN_SESSION, userName);
            session.put(ConstItem.USER_ROLE_IN_SESSION, user.getRole());
            session.put(ConstItem.USER_OBJECT_IN_SESSION, user);

            user.setLastLoginDate(new Date());
            user.setLastLoginIP(request.getRemoteAddr());

            userService.saveOrUpdate(user);

            return SUCCESS;
        }

        errorLogin = true;
        return INPUT;
    }

    @Action(value = "logout", results = {@Result(name = SUCCESS, location = "management_login.jsp")})
    public String logout() throws Exception {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Cache-Control", "no-store");
        response.setDateHeader("Expires", 0);

        session.clear();
        request.getSession().invalidate();

        return SUCCESS;
    }

    @Action(value = "siteMap", results = {@Result(name = SUCCESS, location = "sitemap.jsp")})
    public String siteMap() throws Exception {
        session.clear();
        return SUCCESS;
    }

    @Action(value = "index", results = {@Result(name = SUCCESS, location = "management_index.jsp")})
    public String index() throws Exception {
        return SUCCESS;
    }

    @Action(value = "userAdminManagement", results = {@Result(name = SUCCESS, location = "management_admin.jsp")})
    public String userAdminManagement() throws Exception {
        return SUCCESS;
    }

    @Action(value = "columnsIndex", results = {@Result(name = SUCCESS, location = "columns_index.jsp")})
    public String columnsIndex() throws Exception {
        return SUCCESS;
    }

    @Action(value = "fetchAdministrators", results = {@Result(name = SUCCESS, type = "json", params = {"root", "dataGridView"})})
    public String fetchAdministrators() throws Exception {
        List<Administrator> administratorList = userService.fetchAllAdmins(page, rows);
        int administratorCount = userService.countAllAdmins();

        dataGridView = new HashMap<String, Object>();
        dataGridView.put("rows", administratorList);
        dataGridView.put("total", administratorCount);

        return SUCCESS;
    }

    @Action(value = "userForm", results = {@Result(name = SUCCESS, location = "../form_result.jsp")})
    public String userForm() throws Exception {
        administratorResult = new AdministratorResult();

        String id = userForm.getId();
        if (null == id || id.isEmpty()) {
            userForm.setId(StringUtils.createGuid());
            userForm.setCreateDate(new Date());
            administratorResult.setEdit(false);
            userForm.setLastLoginIP(request.getRemoteAddr());
            userForm.setPassword(ManagementUtils.encryptWithMD5(ConstItem.PASSWORD_PREFIX + userForm.getPassword() + ConstItem.PASSWORD_SUFFIX));
        } else {
            administratorResult.setEdit(true);
        }

        userService.saveOrUpdate(userForm);

        administratorResult.setAdministrator(userForm);
        administratorResult.setSuccessful(true);

        JSONObject jsonObject = JSONObject.fromObject(administratorResult);
        jsonResult = jsonObject.toString();

        return SUCCESS;
    }

    @Action(value = "changePassword", results = {@Result(name = SUCCESS, location = "../form_result.jsp")})
    public String changePassword() throws Exception {
        administratorResult = new AdministratorResult();

        Administrator administrator = (Administrator) session.get(ConstItem.USER_OBJECT_IN_SESSION);
        if (null != administrator) {
            administrator.setPassword(ManagementUtils.encryptWithMD5(ConstItem.PASSWORD_PREFIX + password + ConstItem.PASSWORD_SUFFIX));
            userService.saveOrUpdate(administrator);

            administratorResult.setSuccessful(true);
        } else {
            administratorResult.setSuccessful(false);
        }

        JSONObject jsonObject = JSONObject.fromObject(administratorResult);
        jsonResult = jsonObject.toString();

        return SUCCESS;
    }

    @Action(value = "deleteAdminUser", results = {@Result(name = SUCCESS, type = "json", params = {"root", "administratorResult"})})
    public String deleteAdminUser() throws Exception {
        administratorResult = new AdministratorResult();

        try {
            userService.deleteEntityById(userId);
            administratorResult.setSuccessful(true);
        } catch (AdminException e) {
            administratorResult.setSuccessful(false);
            administratorResult.setErrorMessage(e.getMessage());
        }

        JSONObject jsonObject = JSONObject.fromObject(administratorResult);
        jsonResult = jsonObject.toString();

        return SUCCESS;
    }

    @Action(value = "quartzLog", results = {@Result(name = SUCCESS, type = "stream",
            params = {"contentType", "text/plain", "inputName", "quartzLog",
                    "contentDisposition", "attachment;filename=quartzLog.txt"
                    , "bufferSize", "4096"}), @Result(name = ERROR, location = "../error.jsp")})
    public String downloadQuartzErrorLog() throws Exception {
        Administrator administrator = (Administrator) session.get(ConstItem.USER_OBJECT_IN_SESSION);
        if (null == administrator) {
            return ERROR;
        }

        if (1 != administrator.getRole()) {
            return ERROR;
        }

        return SUCCESS;
    }


    @Action(value = "errorLog", results = {@Result(name = SUCCESS, type = "stream",
            params = {"contentType", "text/plain", "inputName", "errorLog",
                    "contentDisposition", "attachment;filename=errorLog.txt"
                    , "bufferSize", "4096"}), @Result(name = ERROR, location = "../error.jsp")})
    public String downloadErrorLog() throws Exception {
        Administrator administrator = (Administrator) session.get(ConstItem.USER_OBJECT_IN_SESSION);
        if (null == administrator) {
            return ERROR;
        }

        if (1 != administrator.getRole()) {
            return ERROR;
        }

        return SUCCESS;
    }

    @Action(value = "error", results = {@Result(name = SUCCESS, location = "../error.jsp")})
    public String error() throws Exception {
        return SUCCESS;
    }

    public InputStream getQuartzLog() throws Exception {
        logger.debug(System.getProperty("os.name"));
//        return new java.io.FileInputStream("D:\\var\\fengsung\\logs\\fashion_quartz.log");
        return new java.io.FileInputStream("/home/fengsung/logs/fashion_quartz.log");
    }

    public InputStream getErrorLog() throws Exception {
        logger.debug(System.getProperty("os.name"));
//        return new java.io.FileInputStream("D:\\var\\fengsung\\logs\\fashion_error.log");
        return new java.io.FileInputStream("/home/fengsung/logs/fashion_error.log");
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Resource(name = "userService")
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    @Override
    public void setSession(Map<String, Object> session) {
        this.session = session;
    }

    public boolean getErrorLogin() {
        return errorLogin;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

    public Map<String, Object> getDataGridView() {
        return dataGridView;
    }

    public AdministratorResult getAdministratorResult() {
        return administratorResult;
    }

    public Administrator getUserForm() {
        return userForm;
    }

    public void setUserForm(Administrator userForm) {
        this.userForm = userForm;
    }

    public String getJsonResult() {
        return jsonResult;
    }

    @Override
    public void setServletRequest(HttpServletRequest httpServletRequest) {
        request = httpServletRequest;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public ByteArrayInputStream getImageStream() {
        return imageStream;
    }

    public void setImageStream(ByteArrayInputStream imageStream) {
        this.imageStream = imageStream;
    }

    public void setSecurityCode(String securityCode) {
        this.securityCode = securityCode;
    }

    public String getSecurityCode() {
        return securityCode;
    }

    @Override
    public void setServletResponse(HttpServletResponse httpServletResponse) {
        response = httpServletResponse;
    }
}
